package org.teremail.schema;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.teremail.store.Strings;

public class Table {

    private final String name;
    private List<Column> columns;
    private List<List<String>> uniques;

    public Table(String name, List<Column> columns, List<List<String>> uniques) {
        this.name = name;
        this.columns = columns;
        this.uniques = uniques;
    }

    public String getName() {
        return name;
    }

    public List<Column> getColumns() {
        return columns;
    }

    public List<String> generate(Dialect dialect) {
        List<String> statements = new ArrayList<String>();
        statements.add(generateCreate(dialect));
        statements.add(generatePKConstraint(dialect));
        statements.addAll(generateUKConstraint(dialect));
        return Collections.unmodifiableList(statements);
    }
    
    private String generatePKConstraint(Dialect dialect) {
        StringBuilder sb = new StringBuilder();
        sb.append("ALTER TABLE ");
        sb.append(name);
        sb.append(" ADD CONSTRAINT ");
        sb.append(name);
        sb.append("_PK PRIMARY KEY (");
        sb.append(Strings.join(getPKColumnNames(), ", "));
        sb.append(")");
        return sb.toString();
    }
    
    private List<String> generateUKConstraint(Dialect dialect) {
        List<String> results = new ArrayList<String>();
        StringBuilder sb = new StringBuilder();
        int count = 1;
        for (List<String> unique : uniques) {
            sb.append("ALTER TABLE ");
            sb.append(name);
            sb.append(" ADD CONSTRAINT ");
            sb.append(name).append("_UK").append(count++);
            sb.append(" UNIQUE ");
            sb.append("(").append(Strings.join(unique, ", ")).append(")");
            results.add(sb.toString());
            sb.delete(0, sb.length());
        }
        return results;
    }

    private List<String> getPKColumnNames() {
        List<String> cols = new ArrayList<String>();
        for (Column c : getColumns()) {
            if (c.isPrimaryKey()) {
                cols.add(c.getName());
            }
        }
        return cols;
    }

    private String generateCreate(Dialect dialect) {
        StringBuilder sb = new StringBuilder();
        
        sb.append("CREATE TABLE ");
        sb.append(name);
        sb.append(" (");
        for (Iterator<Column> cIt = columns.iterator(); cIt.hasNext();) {
            Column column = cIt.next();
            sb.append(column.generateCreate(dialect));
            if (cIt.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append(")");
        
        return sb.toString();
    }
    
    

}
